{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['_Demo__a', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_a', 'a', 'test']\n",
      "访问a 10\n",
      "访问_a 10\n",
      "访问__a 15\n",
      "['_Demo__a', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_a', 'a', 'test']\n",
      "['_Demo__a', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_a', 'a', 'test']\n",
      "访问a 10\n",
      "访问_a 10\n",
      "访问父类__a: self._Demo__a 10\n"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'Child' object has no attribute '_Child__a'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m/Users/apple/dsc/dsc/22.私有变量/demo.ipynb Cell 1\u001b[0m in \u001b[0;36m<cell line: 36>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=33'>34</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mdir\u001b[39m(d))\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=34'>35</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mdir\u001b[39m(c))\n\u001b[0;32m---> <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=35'>36</a>\u001b[0m c\u001b[39m.\u001b[39;49mtest()\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=36'>37</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mdir\u001b[39m(c))\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=37'>38</a>\u001b[0m \u001b[39mprint\u001b[39m(d\u001b[39m.\u001b[39m__a)\n",
      "\u001b[1;32m/Users/apple/dsc/dsc/22.私有变量/demo.ipynb Cell 1\u001b[0m in \u001b[0;36mChild.test\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=17'>18</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m访问_a\u001b[39m\u001b[39m'\u001b[39m, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_a)    \u001b[39m# 可以访问\u001b[39;00m\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=18'>19</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m访问父类__a: self._Demo__a\u001b[39m\u001b[39m'\u001b[39m, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_Demo__a)\n\u001b[0;32m---> <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=19'>20</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m访问__a\u001b[39m\u001b[39m'\u001b[39m, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m__a)  \u001b[39m# ！ 报错， 无法继承父类的私有变量\u001b[39;00m\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=21'>22</a>\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39ma \u001b[39m=\u001b[39m \u001b[39m20\u001b[39m\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/apple/dsc/dsc/22.%E7%A7%81%E6%9C%89%E5%8F%98%E9%87%8F/demo.ipynb#W0sZmlsZQ%3D%3D?line=22'>23</a>\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_a \u001b[39m=\u001b[39m \u001b[39m20\u001b[39m\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'Child' object has no attribute '_Child__a'"
     ]
    }
   ],
   "source": [
    "# a     普通变量，在外部和子类可以直接访问，\n",
    "# _a    私有变量，在外部和子类可以直接访问，但不建议直接访问\n",
    "# a_    普通变量，如果a与关键字冲突，可加一个下划线以区别\n",
    "# __a   私有变量，在外部和子类不能直接访问，\n",
    "# __a__ 内建函数，不能用这种格式自定义变量\n",
    "\n",
    "\n",
    "class Demo(object):\n",
    "    def __init__(self) -> None:\n",
    "        self.a = 10\n",
    "        self._a = 10   # ！私有变量，不建议直接访问\n",
    "        self.__a = 10  # ！私有变量, 自己能读写，但子类或外部都不能直接访问或修改，（ ! 可以通过_Demo__a 访问)\n",
    "    \n",
    "    def __len__(self): # ! 内建函数，魔法方法，自定义变量不可以用这种方式命名\n",
    "        return 1\n",
    "    \n",
    "    def test(self):\n",
    "        self.__a = 15\n",
    "        print('访问a', self.a)\n",
    "        print('访问_a', self._a)\n",
    "        print('访问__a', self.__a)\n",
    "class Child(Demo):\n",
    "    def test(self):\n",
    "        print('访问a', self.a)      # 可以访问\n",
    "        print('访问_a', self._a)    # 可以访问\n",
    "        print('访问父类__a: self._Demo__a', self._Demo__a)\n",
    "        print('访问__a', self.__a)  # ！ 报错， 无法继承父类的私有变量\n",
    "\n",
    "        self.a = 20\n",
    "        self._a = 20\n",
    "        self.__a = 20              # ！会新建一个Child 实例里的 __a变量 \n",
    "        print('访问a', self.a)\n",
    "        print('访问_a', self._a)\n",
    "        print('访问__a', self.__a)\n",
    "\n",
    "    \n",
    "d = Demo()\n",
    "c = Child()\n",
    "print(dir(d))\n",
    "d.test()\n",
    "print(dir(d))\n",
    "print(dir(c))\n",
    "c.test()\n",
    "print(dir(c))\n",
    "print(d.__a)    # ! 报错\n",
    "print(c.__a)    # ! 报错"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.12 ('opencv')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "b04e532e6ce11d72ca7f2113c964d7a5531c18c5e6d3e97b1c42c6f9a3724305"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
